package com.link2room.rodimus.facade.impl;

import com.link2room.common.constant.DefaultValue;
import com.link2room.common.dto.result.base.MemberSessionDto;
import com.link2room.common.dto.threadlocal.ApiThreadLocal;
import com.link2room.common.entity.BaseEntity;
import com.link2room.common.exception.SysException;
import com.link2room.common.jpa.criteria.CriteriaUtil;
import com.link2room.common.jpa.result.QueryResult;
import com.link2room.common.service.ICommonService;
import com.link2room.common.util.ClassConverUtil;
import com.link2room.common.util.L2RAssert;
import com.link2room.common.util.StringUtil;
import com.link2room.rodimus.constant.CouponConsumeConstant;
import com.link2room.rodimus.constant.ExpressConstant;
import com.link2room.rodimus.dto.param.api.CreateNewExpressParamDto;
import com.link2room.rodimus.dto.param.api.CurrentUserExpressListParamDto;
import com.link2room.rodimus.dto.param.api.ExpressListParamDto;
import com.link2room.rodimus.dto.param.api.ExpressUpdateParamDto;
import com.link2room.rodimus.entity.CouponConsumeBaseEntity;
import com.link2room.rodimus.entity.ExpressBaseEntity;
import com.link2room.rodimus.dto.param.base.ExpressBaseDto;
import com.link2room.rodimus.dto.param.inside.ExpressFindInsideParamDto;
import com.link2room.rodimus.dto.param.inside.ExpressNewInsideParamDto;
import com.link2room.rodimus.facade.IExpressFacadeService;
import com.link2room.rodimus.service.IExpressService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

import static com.link2room.enums.exception.RodimusSysExceptionEnum.EXPRESS_ERROR;


/**
 * Created by LN on 2017/7/28.10:33
 */
@Component("expressFacadeService")
public class ExpressFacadeServiceImpl implements IExpressFacadeService {

    @Resource
    private ICommonService commonService;
    @Resource
    private IExpressService expressService;

    @Override
    @Deprecated
    public void newExpress(CreateNewExpressParamDto paramDto) throws Exception {
        String address = paramDto.getAddress();
        L2RAssert.stringBlank(address, "[address] is null.");
        String mobile = paramDto.getMobile();
        L2RAssert.stringBlank(mobile, "[mobile] is null.");
        String receiveName = paramDto.getReceiverName();
        L2RAssert.stringBlank(receiveName, "[receiveName] is null.");
        String sourceNo = paramDto.getSourceNo();
        L2RAssert.stringBlank(sourceNo, "[sourceNo] is null.");
        String type = paramDto.getSourceType();
        L2RAssert.stringBlank(type, "[type] is null.");

        Integer amount;
        String goodCode;
        String goodName;
        BaseEntity updateSource;
        //根据不同的type 查找不同商品
        if (ExpressConstant.SOURCE_TYPE.COUPON.equals(type)) {
            CouponConsumeBaseEntity couponConsumeFind = new CouponConsumeBaseEntity();
            couponConsumeFind.setConsumeNo(sourceNo);
            CouponConsumeBaseEntity couponConsume = commonService.findOneEQ(CouponConsumeBaseEntity.class, couponConsumeFind);
            if (couponConsume == null) {
                throw new SysException(EXPRESS_ERROR, "没有兑换记录(" + sourceNo + ")");
            }
            amount = couponConsume.getAmount();
            goodCode = couponConsume.getGoodCode();
            goodName = couponConsume.getGoodName();
            L2RAssert.isTrue(CouponConsumeConstant.STA.EXP.equals(couponConsume.getSta()), new SysException(EXPRESS_ERROR, "已经填写过发过地址."));
            couponConsume.setSta(CouponConsumeConstant.STA.EXP);
            updateSource = couponConsume;
        } else {
            throw new SysException(EXPRESS_ERROR, "SourceType error");
        }
        MemberSessionDto memberSession = ApiThreadLocal.getMemberSessionThreadLocal();
        String openid = memberSession.getOpenid();
        ExpressBaseEntity entity = expressService.initExpress();
        entity.setRemark(paramDto.getRemark());
        entity.setLhotelGroupCode(paramDto.getLhotelGroupCode());
        entity.setAddress(address);
        entity.setReceiverName(receiveName);
        entity.setSourceNo(sourceNo);
        entity.setSourceType(type);
        entity.setGoodAmount(amount);
        entity.setGoodCode(goodCode);
        entity.setGoodName(goodName);
        entity.setOpenid(openid);
        entity.setMemberNo(memberSession.getMemberNo());
        entity.setMobile(mobile);

        expressService.saveExpress(entity, updateSource);
    }

    @Override
    public ExpressBaseDto newInsideExpress(ExpressNewInsideParamDto paramDto) throws Exception {
        String address = paramDto.getAddress();
        L2RAssert.stringBlank(address, "[address] is null.");
        String mobile = paramDto.getMobile();
        L2RAssert.stringBlank(mobile, "[mobile] is null.");
        String receiveName = paramDto.getReceiverName();
        L2RAssert.stringBlank(receiveName, "[receiveName] is null.");
        String sourceNo = paramDto.getSourceNo();
        L2RAssert.stringBlank(sourceNo, "[sourceNo] is null.");
        String type = paramDto.getSourceType();
        L2RAssert.stringBlank(type, "[type] is null.");


        ExpressBaseEntity entity = expressService.initExpress();
        entity.setRemark(paramDto.getRemark());
        entity.setLhotelGroupCode(paramDto.getLhotelGroupCode());
        entity.setAddress(address);
        entity.setReceiverName(receiveName);
        entity.setSourceNo(sourceNo);
        entity.setSourceType(type);
        entity.setGoodAmount(paramDto.getGoodAmount());
        entity.setGoodCode(paramDto.getGoodCode());
        entity.setGoodName(paramDto.getGoodName());
        entity.setOpenid(paramDto.getOpenid());
        entity.setMemberNo(paramDto.getMemberNo());
        entity.setMobile(mobile);
        commonService.save(entity);

        return ClassConverUtil.copyProperties(entity, ExpressBaseDto.class);
    }


    @Override
    public QueryResult currentUserExpressList(CurrentUserExpressListParamDto paramDto) throws Exception {
        MemberSessionDto memberSession = ApiThreadLocal.getMemberSessionThreadLocal();
        String openid = memberSession.getOpenid();
        String memberNo = memberSession.getMemberNo();
        String sourceNo = paramDto.getSourceNo();
        L2RAssert.isTrue(StringUtil.isBlank(openid) && StringUtil.isBlank(memberNo), new SysException(EXPRESS_ERROR, "session is Error."));
        ExpressBaseEntity find = new ExpressBaseEntity();
        if (StringUtil.isNotBlank(openid)) {
            find.setOpenid(openid);
        } else {
            find.setMemberNo(memberNo);
        }
        find.setLhotelGroupCode(paramDto.getLhotelGroupCode());
        find.setIsDelivered(paramDto.getIsDelivered());
        find.setSourceType(paramDto.getSourceType());
        find.setSourceNo(sourceNo);
        HashMap<String, String> orderBy = new HashMap<>();
        orderBy.put(CouponConsumeBaseEntity.BaseEntity_.id.toString(), CriteriaUtil.DESC.toString());
        QueryResult<ExpressBaseEntity> qres = commonService.findAllEQ(ExpressBaseEntity.class, find, paramDto.getCurrentPage(), paramDto.getPageSize(), orderBy, null);

        QueryResult dtos = new QueryResult();
        dtos.setTotalrecord(qres.getTotalrecord());
        dtos.setCurrentPage(qres.getCurrentPage());
        dtos.setResultlist(qres.getResultlist().stream()
                .map(entity -> ClassConverUtil.copyProperties(entity, ExpressBaseDto.class))
                .filter(dto -> dto != null)
                .collect(Collectors.toList()));
        return dtos;
    }

    @Override
    public QueryResult expressList(ExpressListParamDto paramDto) throws Exception {
        String lhotelGroupCode = paramDto.getLhotelGroupCode();
        L2RAssert.stringBlank(lhotelGroupCode, "[lhotelGroupCode] is null.");
        HashMap<String, String> orderBy = new HashMap<>();
        orderBy.put(CouponConsumeBaseEntity.BaseEntity_.id.toString(), CriteriaUtil.DESC.toString());
        ExpressBaseEntity find = new ExpressBaseEntity();
        find.setLhotelGroupCode(paramDto.getLhotelGroupCode());
        find.setIsDelivered(paramDto.getIsDelivered());
        find.setSourceType(paramDto.getSourceType());
        find.setSourceNo(paramDto.getSourceNo());
        find.setMobile(paramDto.getMobile());
        find.setMemberNo(paramDto.getMemberNo());
        find.setThirdExpressNo(paramDto.getThirdExpressNo());
        find.setReceiverName(paramDto.getReceiverName());
        find.setGoodCode(paramDto.getGoodCode());
        QueryResult<ExpressBaseEntity> qres = commonService.findAllEQ(ExpressBaseEntity.class, find, paramDto.getCurrentPage(), paramDto.getPageSize(), orderBy, null);
        if (qres == null || CollectionUtils.isEmpty(qres.getResultlist())) {
            qres = new QueryResult<>();
            qres.setCurrentPage(1);
            qres.setTotalrecord(0);
            qres.setResultlist(Collections.emptyList());
            return qres;
        } else {
            QueryResult dtos = new QueryResult();
            dtos.setTotalrecord(qres.getTotalrecord());
            dtos.setCurrentPage(qres.getCurrentPage());
            dtos.setResultlist(qres.getResultlist().stream()
                    .map(entity -> ClassConverUtil.copyProperties(entity, ExpressBaseDto.class))
                    .filter(dto -> dto != null)
                    .collect(Collectors.toList()));
            return dtos;
        }
    }

    @Override
    public void updateExpress(ExpressUpdateParamDto paramDto) throws Exception {
        String company = paramDto.getExpressCompany();
        String isDelivered = paramDto.getIsDelivered();
        String thirdExpressNo = paramDto.getThirdExpressNo();
        String expressNo = paramDto.getExpressNo();
        L2RAssert.stringBlank(company, "[company] is null.");
        L2RAssert.stringBlank(expressNo, "[expressNo] is null.");
        L2RAssert.stringBlank(thirdExpressNo, "[thirdExpressNo] is null.");
        L2RAssert.stringBlank(isDelivered, "[isDelivered] is null.");
        L2RAssert.isTrue(!DefaultValue.T.equals(isDelivered) && !DefaultValue.F.equals(isDelivered), new SysException(EXPRESS_ERROR, "[isDelivered] is not valid"));


        ExpressBaseEntity find = new ExpressBaseEntity();
        find.setExpressNo(expressNo);
        ExpressBaseEntity entity = commonService.findOneEQ(ExpressBaseEntity.class, find);
        L2RAssert.isTrue(entity == null, new SysException(EXPRESS_ERROR, "[expressNo]错误"));
        entity.setIsDelivered(isDelivered);
        entity.setThirdExpressNo(thirdExpressNo);
        entity.setExpressCompany(company);
        commonService.merge(entity);
    }

    @Override
    public QueryResult<ExpressBaseDto> findExpressBaseDtos(ExpressFindInsideParamDto paramDto) throws Exception {
        String mobile = paramDto.getMobile();
        String expressNo = paramDto.getExpressNo();
        String goodCode = paramDto.getGoodCode();
        String isDelivered = paramDto.getIsDelivered();
        String sourceNo = paramDto.getSourceNo();
        String sourceType = paramDto.getSourceType();
        String thirdExpressNo = paramDto.getThirdExpressNo();
        String lhotelGroupCode = paramDto.getLhotelGroupCode();
        L2RAssert.isTrue(
                StringUtil.isBlank(mobile) &&
                        StringUtil.isBlank(expressNo) &&
                        StringUtil.isBlank(goodCode) &&
                        StringUtil.isBlank(isDelivered) &&
                        StringUtil.isBlank(sourceNo) &&
                        StringUtil.isBlank(sourceType) &&
                        StringUtil.isBlank(thirdExpressNo) &&
                        StringUtil.isBlank(lhotelGroupCode)
                , new SysException(EXPRESS_ERROR, "请求参数不能全为空."));

        ExpressBaseEntity find = new ExpressBaseEntity();
        find.setLhotelGroupCode(lhotelGroupCode);
        find.setExpressNo(expressNo);
        find.setGoodCode(goodCode);
        find.setIsDelivered(isDelivered);
        find.setSourceNo(sourceNo);
        find.setSourceType(sourceType);
        find.setThirdExpressNo(thirdExpressNo);
        find.setMobile(mobile);
        QueryResult<ExpressBaseEntity> qres = commonService.findAllEQ(ExpressBaseEntity.class, find, paramDto.getCurrentPage(), paramDto.getPageSize());

        if (qres == null || CollectionUtils.isEmpty(qres.getResultlist())) {
            QueryResult<ExpressBaseDto> res = new QueryResult<>();
            res.setTotalrecord(0);
            res.setCurrentPage(0);
            return res;
        } else {
            List<ExpressBaseDto> list = qres.getResultlist().stream()
                    .map(entity -> ClassConverUtil.copyProperties(entity, ExpressBaseDto.class))
                    .collect(Collectors.toList());
            QueryResult<ExpressBaseDto> res = new QueryResult<>();
            res.setTotalrecord(qres.getTotalrecord());
            res.setCurrentPage(qres.getCurrentPage());
            res.setResultlist(list);
            return res;
        }
    }
}
